import md5 from "md5";
const type_map = {
  问答: "input",
  单选: "radio",
  多选: "checkbox",
  判断: "tof",
};

let instance;
export default class QaPool {
  originString = "";
  questionLines = [];
  questions = [];
  parseLog = [];

  regexEmptyLine = /\n\s*\n/gm;
  regexNewLine = /\n/gm;
  regexTitle = /^(?<index>\d+)[．.、][\s]*(?<title>.*)$/;
  regexAnswerInTitleEnd =
    /[(（]\s*(?<answer>对|错|√|×|[a-zA-ZＡ-ｚ]+)\s*[)）]\s{0,}$/;
  regexAnswerInTitleLine =
    /[(（]\s*(?<answer>对|错|√|×|[a-zA-ZＡ-ｚ]+)\s*[)）]/g;
  regexTypeInTitle = /[\[【]\s*(?<typeCN>\W+)\s*[\]】]/;
  regexOption = /^[a-zA-ZＡ-ｚ]\s*[．.、\s]?\s*\S*/;
  regexOptions = /(?<value>[a-zA-ZＡ-ｚ])\s*[．.、\s]?\s*(?<text>[^\n]*)/g;
  regexDesc = /^解析[:：]\s*(?<desc>.*)$/;
  regexAnswer = /^(正确)?答案[:：]\s*(?<answer>.+)/;
  // regexTOF = /^[(（]\s*(?<answer>对|错|√|×)\s*[)）]/;
  regexTOF = /^对|错|√|×$/;

  constructor(strOrigin) {
    if (instance && instance.originString === strOrigin.trim()) {
      return instance;
    }
    this.originString = strOrigin.trim();
    instance = this;
    this.parseLine();
    // console.log(this.questionLines);
  }
  setSource(strOrigin) {
    this.originString = strOrigin.trim();
  }

  toHalfWidth(str) {
    return str.replace(/[Ａ-Ｚａ-ｚ０-９]/g, function (s) {
      return String.fromCharCode(s.charCodeAt(0) - 0xfee0);
    });
  }
  /**
   * 拆分每一个问题的字符串为字符串数组
   */
  parseLine() {
    const that = this;
    const str = that.originString;
    let lines = str.split(that.regexNewLine);
    lines = lines.filter((line) => line.trim() !== "");

    let tmpQuestionStringArr = [];
    lines.forEach((line, index) => {
      line = line.trim();
      if (that.regexTitle.test(line)) {
        if (tmpQuestionStringArr.length > 0) {
          that.questionLines.push(tmpQuestionStringArr);
          tmpQuestionStringArr = [];
        }
      }
      tmpQuestionStringArr.push(line);
    });
    if (tmpQuestionStringArr.length > 0) {
      that.questionLines.push(tmpQuestionStringArr);
    }
  }

  parseQuestions() {
    const that = this;
    that.questions = [];
    that.parseLog = [];
    this.questionLines.forEach((questionStringArr) => {
      try {
        const { question, err } = that.parseQuestion(questionStringArr);
        if (err !== null) {
          that.parseLog.push({
            type: err.type,
            message: err.errMsg,
            line: questionStringArr.join("\n") || "",
          });
        }
        if (question) {
          if (
            that.questions.find((q) => q.md5 === question.md5) === undefined
          ) {
            that.questions.push(question);
          } else {
            const log = `${question.index}、 ${question.title} `;

            that.parseLog.push({
              type: "error",
              message: "重复题目",
              line: log,
            });
          }
        }
      } catch (e) {
        that.parseLog.push({
          type: "error",
          message: e.message,
          line: questionStringArr.join("\n") || "",
        });
        return;
      }
    });
    return that.questions;
  }

  parseQuestion(questionStringArr) {
    const that = this;
    const question = {};
    let err = null;
    questionStringArr.forEach((line) => {
      // console.log(`line:${line}:`);
      if (that.regexTitle.test(line)) {
        const titleMatch = line.match(that.regexTitle);
        // console.log(line, "Title");
        question.index = titleMatch.groups.index;

        let tmpTitle = titleMatch.groups.title;
        // console.log("原标题：", tmpTitle);
        if (that.regexTypeInTitle.test(tmpTitle)) {
          // console.log("有类型");
          const typeMatch = tmpTitle.match(that.regexTypeInTitle);
          question.typeText = typeMatch.groups.typeCN;
          tmpTitle = tmpTitle.replace(that.regexTypeInTitle, "");
          // console.log("替换类型后", tmpTitle);
        }

        // 开始处理答案
        let tmpAnswerArr = [];
        const answerMatch = tmpTitle.matchAll(that.regexAnswerInTitleLine);
        for (const match of answerMatch) {
          tmpAnswerArr.push(
            that.toHalfWidth(match.groups.answer.toUpperCase())
          );
        }

        if (tmpAnswerArr.length > 0) {
          if (
            tmpAnswerArr.length === 1 &&
            that.regexAnswerInTitleEnd.test(tmpTitle)
          ) {
            tmpTitle = tmpTitle.replace(that.regexAnswerInTitleEnd, "");
          } else {
            tmpTitle = tmpTitle.replace(that.regexAnswerInTitleLine, "(  )");
          }
          // console.log("替换答案后", tmpTitle);
        }
        question.answer = tmpAnswerArr.join("");
        question.title = tmpTitle;
      } else if (that.regexOption.test(line)) {
        question.options = question.options || [];
        const optionMatch = line.matchAll(that.regexOptions);
        for (const match of optionMatch) {
          question.options.push({
            value: that.toHalfWidth(match.groups.value.toUpperCase()),
            text: match.groups.text,
          });
        }
      } else if (that.regexDesc.test(line)) {
        const desc = line.match(that.regexDesc);
        // console.log(line, "desc");
        question.desc = desc.groups.desc;
      } else if (that.regexAnswer.test(line)) {
        const answerMatch = line.match(that.regexAnswer);
        // console.log(line, "Answer");
        // console.log(answerMatch);
        question.answer = answerMatch.groups.answer.trim();
      }
    });
    if (!question.title) {
      return {
        question: null,
        err: {
          type: "error",
          errMsg: "本行文字不是标题",
        },
      };
    }
    question.md5 = md5(question.title + question?.options?.join("") || "");
    // console.log(JSON.stringify(question));
    if (question?.options?.length || 0) {
      question.answer = [...question.answer];
      if (question.answer.length === 0) {
        err = {
          type: "warning",
          errMsg: "没有答案",
        };
        question.typeText = "单选";
      }

      if (question.answer.length === 1) {
        question.typeText = "单选";
      } else if (question.answer.length > 1) {
        question.typeText = "多选";
      }
    } else if (that.regexTOF.test(question.answer)) {
      question.typeText = "判断";
      if (question.answer === "对" || question.answer === "√") {
        question.answer = true;
      } else if (question.answer === "错" || question.answer === "×") {
        question.answer = false;
      }
    } else {
      question.typeText = "问答";
    }
    question.type = type_map[question.typeText];

    return {
      question,
      err,
    };
  }

  getQuestions() {
    this.parseQuestions();
    return {
      questions: this.questions,
      logs: this.parseLog,
    };
  }
}
